﻿using System.ComponentModel;
using BalanceManager.Helpers;
using BalanceManager.Model;
using System;
using System.Collections.Generic;
using BalanceManager.Services;

namespace BalanceManager.ViewModels
{
    public class AddFundFlowViewModel : BaseViewModel, INavigable
    {
        private IDataService _dataService;
        private bool isNewInstance;
        private bool isEditing;
        private FlowType currentFlowType;

        public AddFundFlowViewModel(IDataService dataService)
        {
            if (dataService == null)
                throw new ArgumentException("dataService");
            isNewInstance = true;
            _dataService = dataService;

            _saveCommand = new DelegateCommand(SaveAction, CanSaveAction);
            _selectCategoryCommand = new DelegateCommand(SelectCategoryAction);
            recentlyItemUpdateCommand = new DelegateCommand(RecentlyItemUpdateAction);
        }

        void CurrentFundFlowOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
        {
            OnPropertyChanged("CurrentFundFlow");
            OnPropertyChanged("SelectedItemText");
            SaveCommand.RaiseCanExecuteChanged();
        }

        private List<Item> recentlyUsedItems;
        public List<Item> RecentlyUsedItems
        {
            get
            {
                if (recentlyUsedItems == null)
                    recentlyUsedItems = _dataService.RecentlyUsedItems(10);
                return recentlyUsedItems;
            }
        }

        FundFlow _currentFundFlow;
        public FundFlow CurrentFundFlow
        {
            get { return _currentFundFlow; }
            set
            {
                if (_currentFundFlow != value)
                {
                    if (_currentFundFlow != null)
                        _currentFundFlow.PropertyChanged -= CurrentFundFlowOnPropertyChanged;
                    _currentFundFlow = value;
                    OnPropertyChanged();
                    OnPropertyChanged("SelectedItemText");
                    if (_currentFundFlow != null)
                        _currentFundFlow.PropertyChanged += CurrentFundFlowOnPropertyChanged;
                    SaveCommand.RaiseCanExecuteChanged();
                }
            }
        }

        public string SelectedItemText
        {
            get
            {
                return (_currentFundFlow == null || _currentFundFlow.ItemId == 0) 
                    ? "Не выбрано" 
                    :  _dataService.GetItemById(_currentFundFlow.ItemId).Name;
            }
        }

        readonly DelegateCommand _saveCommand;
        public DelegateCommand SaveCommand
        {
            get { return _saveCommand; }
        }

        void SaveAction(object o)
        {
            if (isEditing)
                UpdateFundFlow();
            else
                InsertNewFundFlow();
        }

        bool CanSaveAction(object o)
        {
            return _currentFundFlow != null && 
                _currentFundFlow.FlowType != FlowType.None && 
                _currentFundFlow.Amount > 0 && 
                _currentFundFlow.ItemId > 0;
        }

        void InsertNewFundFlow()
        {
            _dataService.SaveFundFlow(_currentFundFlow);
            ResetValues();
            SaveCommand.RaiseCanExecuteChanged();
            ApplicationController.Default.RemoveBackEntry();
        }

        void UpdateFundFlow()
        {
            _dataService.SaveFundFlow(_currentFundFlow);
            ApplicationController.Default.NavigateTo(ViewType.Main);
            ApplicationController.Default.RemoveBackEntry();
            ApplicationController.Default.RemoveBackEntry();
            ApplicationController.Default.RemoveBackEntry();
        }

        readonly DelegateCommand _selectCategoryCommand;
        public DelegateCommand SelectCategoryCommand
        {
            get { return _selectCategoryCommand; } 
        }

        void SelectCategoryAction(object o)
        {
            ApplicationController.Default.NavigationParameters.Add("fundFlowParam", 
                new FundFlowEditableParameter() {EditingMode = isEditing, FundFlow = CurrentFundFlow});
            ApplicationController.Default.NavigateTo(ViewType.Items);
        }

        void ResetValues()
        {
            CurrentFundFlow = new FundFlow(currentFlowType);
        }

        private readonly DelegateCommand recentlyItemUpdateCommand;

        public DelegateCommand RecentlyItemUpdateCommand
        {
            get { return recentlyItemUpdateCommand; }
        }

        private void RecentlyItemUpdateAction(object o)
        {
            var id = (int)o;
            _currentFundFlow.ItemId = id;
        }

        public void Activate(IDictionary<string, object> parameters)
        {
            if (isNewInstance)
            {
                var param = (FundFlowEditableParameter)parameters["fundFlowParam"];
                isEditing = param.EditingMode;
                currentFlowType = param.FundFlow.FlowType;
                CurrentFundFlow = param.FundFlow;
                isNewInstance = false;
            }
        }

        public void Deactivate(IDictionary<string, object> parameters) { }
    }
}
